#include "cgzCTcpWC.h"
#include "cgzCThreadPool.h"

cgzCSendWC::cgzCSendWC(
    const char *data,
    const int len,
    int t,
    bool mask,
    const char *reason)
    : cgzCSendC()
{
    webscoket_encode_message(data, len, t, mask, &m_data, m_len, reason);
}

cgzCSendWC::cgzCSendWC(cgzHeader &header, const int ufd)
    : cgzCSendC()
{
    // 开辟控制
    m_len = (header.len + sizeof(cgzGateHeader));
    m_data = (char *)malloc(m_len);
    // 构造头部
    auto &gateHeader = *(cgzGateHeader *)m_data;
    gateHeader.mid = header.mid;
    gateHeader.len = header.len;
    gateHeader.cid = header.cid;
    gateHeader.all = m_len;
    gateHeader.ufd = ufd;
}

cgzCSendWC::~cgzCSendWC()
{
}

cgzCRecvWC::cgzCRecvWC(
    int orgid,
    int tarid,
    const char *data,
    const int len,
    int t)
    : cgzCRecvC(orgid, tarid, data, len),
      rt(t)
{
}

cgzCRecvWC::~cgzCRecvWC()
{
}

cgzCTcpWC::cgzCTcpWC(
    cgzCThreadPool *pool,
    const char *name,
    const std::string ip,
    const int port,
    const int cid)
    : cgzCTcpC(pool, name, ip, port, cid)

{
    m_tenum = cgzETask::CTcpWC;
    auto node = malloc(sizeof(cgzCWDecode));
    m_pDecodeWC = new (node) cgzCWDecode();
}

cgzCTcpWC::~cgzCTcpWC()
{
}

bool cgzCTcpWC::tcpsend()
{
    cgzCTcpC::tcpsend();
    return true;
}

bool cgzCTcpWC::connect(bool is_hand)
{
    is_hand = false;
    cgzCTcpC::connect(is_hand);
    sendhandshake();
    return true;
}

bool cgzCTcpWC::handshake()
{
    m_hand = true;
    sendaccept();
    return true;
}

bool cgzCTcpWC::sticking()
{
    if (!m_hand)
    {
        // 握手判断
        char tail[4] = {0, 0, 0, 0};
        if (!m_readCire.read(tail, sizeof(tail)))
        {
            return false;
        }

        if (tail[0] == '\r' && tail[1] == '\n' && tail[2] == '\r' && tail[3] == '\n')
        {
            std::string str;
            m_readCire.read(str);
            if (websocket_validate_handshake(str, m_key))
            {
                m_readCire.clear();
                m_hand = true;
                handshake();
                cgz_this_error("websocket handshake success name:{}", m_name);
            }
            else
            {
                m_readCire.clear();
                // 关闭连接
                cgzCSendWC wc((char *)close_auth, sizeof(close_auth), WEBSOCKET_SEND_DISC, "认证失败");
                m_sendCire.push(wc.m_data, wc.m_len);
                cgz_this_error("websocket handshake failed name:{}", m_name);
            }
        }
        return false;
    }

    cgzCWDecode &de = *m_pDecodeWC;
    while (webscoket_decode_message(m_readCire, de))
    {
        if (!decodeProc(de))
        {
            void *node = malloc(sizeof(cgzCRecvWC));
            auto readC = new (node) cgzCRecvWC(getId(), m_cid, de.decode_data, de.decode_len, de.rt);
            // 将包放入队列
            todoret(readC);
        }

        // 重置解码器
        m_pDecodeWC = new (m_pDecodeWC) cgzCWDecode();
    }
    return false;
}

void cgzCTcpWC::sendhandshake()
{
    m_key = websocket_generate_handkey();
    std::string str = websocket_generate_handshake(m_key, m_ip, m_port);
    cgzCSendWC wc(str.c_str(), str.length(), WEBSOCKET_SEND_HAND);
    m_sendCire.push(wc.m_data, wc.m_len);
}

bool cgzCTcpWC::decodeProc(cgzCWDecode &de)
{
    return false;
}